--- lirc-0.8.6.orig/drivers/lirc_dev/lirc_dev.h	2009/03/15 09:34:00	1.37
+++ lirc-0.8.6/drivers/lirc_dev/lirc_dev.h	2010/01/23 16:28:07	1.39
@@ -4,7 +4,7 @@
  * (L) by Artur Lipowski <alipowski@interia.pl>
  *        This code is licensed under GNU GPL
  *
- * $Id: lirc_dev.h,v 1.37 2009/03/15 09:34:00 lirc Exp $
+ * $Id: lirc_dev.h,v 1.39 2010/01/23 16:28:07 lirc Exp $
  *
  */
 
@@ -30,14 +30,19 @@
 
 struct lirc_buffer {
 	wait_queue_head_t wait_poll;
-	spinlock_t lock;
+	spinlock_t fifo_lock;
 	unsigned int chunk_size;
 	unsigned int size; /* in chunks */
 	/* Using chunks instead of bytes pretends to simplify boundary checking
 	 * And should allow for some performance fine tunning later */
 #ifdef LIRC_HAVE_KFIFO
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
 	struct kfifo *fifo;
 #else
+	struct kfifo fifo;
+	u8 fifo_initialized;
+#endif
+#else
 	unsigned int fill; /* in chunks */
 	int head, tail;    /* in chunks */
 	unsigned char *data;
@@ -47,12 +52,12 @@
 static inline void lirc_buffer_lock(struct lirc_buffer *buf,
 				    unsigned long *flags)
 {
-	spin_lock_irqsave(&buf->lock, *flags);
+	spin_lock_irqsave(&buf->fifo_lock, *flags);
 }
 static inline void lirc_buffer_unlock(struct lirc_buffer *buf,
 				      unsigned long *flags)
 {
-	spin_unlock_irqrestore(&buf->lock, *flags);
+	spin_unlock_irqrestore(&buf->fifo_lock, *flags);
 }
 static inline void _lirc_buffer_clear(struct lirc_buffer *buf)
 {
@@ -64,10 +69,21 @@
 static inline void lirc_buffer_clear(struct lirc_buffer *buf)
 {
 #ifdef LIRC_HAVE_KFIFO
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
 	if (buf->fifo)
 		kfifo_reset(buf->fifo);
 #else
 	unsigned long flags;
+
+	if (buf->fifo_initialized) {
+		spin_lock_irqsave(&buf->fifo_lock, flags);
+		kfifo_reset(&buf->fifo);
+		spin_unlock_irqrestore(&buf->fifo_lock, flags);
+	}
+#endif
+#else
+	unsigned long flags;
+
 	lirc_buffer_lock(buf, &flags);
 	_lirc_buffer_clear(buf);
 	lirc_buffer_unlock(buf, &flags);
@@ -77,31 +93,47 @@
 				    unsigned int chunk_size,
 				    unsigned int size)
 {
+	int ret = 0;
+
 	init_waitqueue_head(&buf->wait_poll);
-	spin_lock_init(&buf->lock);
+	spin_lock_init(&buf->fifo_lock);
 #ifndef LIRC_HAVE_KFIFO
 	_lirc_buffer_clear(buf);
 #endif
 	buf->chunk_size = chunk_size;
 	buf->size = size;
 #ifdef LIRC_HAVE_KFIFO
-	buf->fifo = kfifo_alloc(size*chunk_size, GFP_KERNEL, &buf->lock);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
+	buf->fifo = kfifo_alloc(size*chunk_size, GFP_KERNEL, &buf->fifo_lock);
 	if (!buf->fifo)
 		return -ENOMEM;
 #else
+	ret = kfifo_alloc(&buf->fifo, size * chunk_size, GFP_KERNEL);
+	if (ret == 0)
+		buf->fifo_initialized = 1;
+#endif
+#else
 	buf->data = kmalloc(size*chunk_size, GFP_KERNEL);
 	if (buf->data == NULL)
 		return -ENOMEM;
 	memset(buf->data, 0, size*chunk_size);
 #endif
-	return 0;
+
+	return ret;
 }
 static inline void lirc_buffer_free(struct lirc_buffer *buf)
 {
 #ifdef LIRC_HAVE_KFIFO
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
 	if (buf->fifo)
 		kfifo_free(buf->fifo);
 #else
+	if (buf->fifo_initialized) {
+		kfifo_free(&buf->fifo);
+		buf->fifo_initialized = 0;
+	}
+#endif
+#else
 	kfree(buf->data);
 	buf->data = NULL;
 	buf->head = 0;
@@ -111,6 +143,25 @@
 	buf->size = 0;
 #endif
 }
+
+#ifdef LIRC_HAVE_KFIFO
+static inline int lirc_buffer_len(struct lirc_buffer *buf)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
+	return kfifo_len(buf->fifo);
+#else
+	int len;
+	unsigned long flags;
+
+	spin_lock_irqsave(&buf->fifo_lock, flags);
+	len = kfifo_len(&buf->fifo);
+	spin_unlock_irqrestore(&buf->fifo_lock, flags);
+
+	return len;
+#endif
+}
+#endif
+
 #ifndef LIRC_HAVE_KFIFO
 static inline int  _lirc_buffer_full(struct lirc_buffer *buf)
 {
@@ -120,7 +171,7 @@
 static inline int  lirc_buffer_full(struct lirc_buffer *buf)
 {
 #ifdef LIRC_HAVE_KFIFO
-	return kfifo_len(buf->fifo) == buf->size * buf->chunk_size;
+	return lirc_buffer_len(buf) == buf->size * buf->chunk_size;
 #else
 	unsigned long flags;
 	int ret;
@@ -139,7 +190,7 @@
 static inline int  lirc_buffer_empty(struct lirc_buffer *buf)
 {
 #ifdef LIRC_HAVE_KFIFO
-	return !kfifo_len(buf->fifo);
+	return !lirc_buffer_len(buf);
 #else
 	unsigned long flags;
 	int ret;
@@ -158,7 +209,7 @@
 static inline int  lirc_buffer_available(struct lirc_buffer *buf)
 {
 #ifdef LIRC_HAVE_KFIFO
-	return buf->size - (kfifo_len(buf->fifo) / buf->chunk_size);
+	return buf->size - (lirc_buffer_len(buf) / buf->chunk_size);
 #else
 	unsigned long flags;
 	int ret;
@@ -177,21 +228,30 @@
 	buf->fill -= 1;
 }
 #endif
-static inline void lirc_buffer_read(struct lirc_buffer *buf,
-				    unsigned char *dest)
+static inline unsigned int lirc_buffer_read(struct lirc_buffer *buf,
+					    unsigned char *dest)
 {
+	unsigned int ret = 0;
+
 #ifdef LIRC_HAVE_KFIFO
-	if (kfifo_len(buf->fifo) >= buf->chunk_size)
-		kfifo_get(buf->fifo, dest, buf->chunk_size);
+	if (lirc_buffer_len(buf) >= buf->chunk_size)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
+		ret = kfifo_get(buf->fifo, dest, buf->chunk_size);
+#else
+		ret = kfifo_out_locked(&buf->fifo, dest, buf->chunk_size,
+				       &buf->fifo_lock);
+#endif
 #else
 	unsigned long flags;
 	lirc_buffer_lock(buf, &flags);
 	_lirc_buffer_read_1(buf, dest);
 	lirc_buffer_unlock(buf, &flags);
 #endif
+
+	return ret;
 }
 #ifndef LIRC_HAVE_KFIFO
-static inline void _lirc_buffer_write_1(struct lirc_buffer *buf,
+static inline  _lirc_buffer_write_1(struct lirc_buffer *buf,
 				      unsigned char *orig)
 {
 	memcpy(&buf->data[buf->tail*buf->chunk_size], orig, buf->chunk_size);
@@ -199,17 +259,26 @@
 	buf->fill++;
 }
 #endif
-static inline void lirc_buffer_write(struct lirc_buffer *buf,
-				     unsigned char *orig)
+static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf,
+					     unsigned char *orig)
 {
+	unsigned int ret = 0;
+
 #ifdef LIRC_HAVE_KFIFO
-	kfifo_put(buf->fifo, orig, buf->chunk_size);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
+	ret = kfifo_put(buf->fifo, orig, buf->chunk_size);
+#else
+	ret = kfifo_in_locked(&buf->fifo, orig, buf->chunk_size,
+			      &buf->fifo_lock);
+#endif
 #else
 	unsigned long flags;
 	lirc_buffer_lock(buf, &flags);
 	_lirc_buffer_write_1(buf, orig);
 	lirc_buffer_unlock(buf, &flags);
 #endif
+
+	return ret;
 }
 #ifndef LIRC_HAVE_KFIFO
 static inline void _lirc_buffer_write_n(struct lirc_buffer *buf,
@@ -234,17 +303,26 @@
 	buf->fill += count;
 }
 #endif
-static inline void lirc_buffer_write_n(struct lirc_buffer *buf,
-				       unsigned char *orig, int count)
+static inline unsigned int lirc_buffer_write_n(struct lirc_buffer *buf,
+					       unsigned char *orig, int count)
 {
+	unsigned int ret = 0;
+
 #ifdef LIRC_HAVE_KFIFO
-	kfifo_put(buf->fifo, orig, count * buf->chunk_size);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
+	ret = kfifo_put(buf->fifo, orig, count * buf->chunk_size);
+#else
+	ret = kfifo_in_locked(&buf->fifo, orig, count * buf->chunk_size,
+			      &buf->fifo_lock);
+#endif
 #else
 	unsigned long flags;
 	lirc_buffer_lock(buf, &flags);
 	_lirc_buffer_write_n(buf, orig, count);
 	lirc_buffer_unlock(buf, &flags);
 #endif
+
+	return ret;
 }
 
 struct lirc_driver {
